package com.atguigu.lease.web.app.service.impl;


import com.atguigu.lease.common.constants.RedisConstant;
import com.atguigu.lease.common.exception.LeaseException;
import com.atguigu.lease.common.jwt.JwtUtil;
import com.atguigu.lease.common.result.ResultCodeEnum;
import com.atguigu.lease.model.entity.UserInfo;
import com.atguigu.lease.model.enums.BaseStatus;
import com.atguigu.lease.web.app.service.LoginService;
import com.atguigu.lease.web.app.service.UserInfoService;
import com.atguigu.lease.web.app.vo.user.LoginVo;
import com.atguigu.lease.web.app.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Autowired
    private UserInfoService userInfoService;

    @Override
    public void getCode(String phone) {
        //获取手机号
        String key = RedisConstant.APP_LOGIN_PREFIX + phone;

        //超时判定
        if (redisTemplate.hasKey(key)) {
            Long timeRemaining = redisTemplate.getExpire(key,TimeUnit.SECONDS);
            if (RedisConstant.APP_LOGIN_CODE_TTL_SEC - timeRemaining < RedisConstant.APP_LOGIN_CODE_RESEND_TIME_SEC) {
                throw new LeaseException(ResultCodeEnum.APP_SEND_SMS_TOO_OFTEN);
            }
        }

        //生成验证码
        String code = String.valueOf(new Random().nextInt(900000) + 100000);
        //存到Redis
        redisTemplate.opsForValue().set(key,code,RedisConstant.APP_LOGIN_CODE_TTL_SEC, TimeUnit.SECONDS);
        //发送短信
        System.out.println("验证码:" + code);
    }

    @Override
    public String login(LoginVo loginVo) {
        //1.校验验证码
        String code = loginVo.getCode();
        //验证码为空
        if (ObjectUtils.isEmpty(code)) {
            throw new LeaseException(ResultCodeEnum.APP_LOGIN_CODE_EMPTY);
        }

        String phone = loginVo.getPhone();
        String key = RedisConstant.APP_LOGIN_PREFIX + phone;

        if (redisTemplate.hasKey(key)) {
            //验证码错误
            String codeRedis = (String) redisTemplate.opsForValue().get(key);
            if (!code.equals(codeRedis)) {
                throw new LeaseException(ResultCodeEnum.APP_LOGIN_CODE_ERROR);
            }
        } else {
            //验证码过期
            throw new LeaseException(ResultCodeEnum.APP_LOGIN_CODE_EXPIRED);
        }

        //2.注册+登录
        LambdaQueryWrapper<UserInfo> userInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userInfoLambdaQueryWrapper.eq(UserInfo::getPhone, phone);
        //2.1注册
/*      方案1(两次查询)
        long count = userInfoService.count(userInfoLambdaQueryWrapper);
        if (count == 0) {
            UserInfo userInfo = UserInfo.builder()
                    .phone(phone)
                    .avatarUrl("http://www.baidu.com/img/bd_logo.png")
                    .nickname("匿名用户" + phone.substring(7))
                    .status(BaseStatus.ENABLE)
                    .build();
            userInfoService.save(userInfo);
        }
*/
        //方案2(一次查询)
        UserInfo userInfo = userInfoService.getOne(userInfoLambdaQueryWrapper);
        if (userInfo == null) {
            userInfo = UserInfo.builder()
                    .phone(phone)
                    .avatarUrl("http://www.baidu.com/img/bd_logo.png")
                    .nickname("匿名用户" + phone.substring(7))
                    .status(BaseStatus.ENABLE)
                    .build();
            userInfoService.save(userInfo);
        }

        //2.2登录
        //判断是否被封禁
        if (!BaseStatus.ENABLE.equals(userInfo.getStatus())) {
            throw new LeaseException(ResultCodeEnum.APP_ACCOUNT_DISABLED_ERROR);
        }
        //返回token
        String token = JwtUtil.createToken(userInfo.getId(), phone);
        return token;
    }

    @Override
    public UserInfoVo info(String token) {
        //在token中解析出Id
        Integer id = (Integer) JwtUtil.parseToken(token).get("userId");
        //获取用户全部信息
        UserInfo userInfo = userInfoService.getById(id);
        //选择性返回给前端
        return new UserInfoVo(userInfo.getNickname(), userInfo.getAvatarUrl());
    }


}















